﻿//using BaseUtils;
//using BaseUtils.Helper;
//using BaseUtils.Logger;
//using BaseUtils.Utils;
//using Service.src.Flow.JavaScript;
//using Service.src.Model.Folw;
//using Service.src.NW.Enum;
//using Service.src.NW.Model;
//using Service.src.NW.Model.Enum;
//using Service.src.NW.Model.Folw;
//using Service.src.NW.Processor.Core;
//using System;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.Diagnostics;
//using System.Linq;
//using System.Threading;
//using System.Threading.Tasks;

//namespace Service.src.Flow.Server
//{
//    public class FlowProcessor : BaseProcessor
//    {

//        /// <summary>
//        /// 获取流程
//        /// </summary>
//        /// <param name="FlowId"></param>
//        /// <returns></returns>
//        public static FlowRoot GetFlow(string Path, string FolwName)
//        {
//            FlowRoot Flow = FileHelper.ReadContent<FlowRoot>($"{Path}{FolwName}.nw");
//            if (Flow == null)
//            {
//                throw new Exception("");
//            }
//            return Flow;
//        }

//        /// <summary>
//        /// 根据流程ID获取流程信息
//        /// </summary>
//        /// <param name="FlowId"></param>
//        /// <returns></returns>
//        /// <exception cref="Exception"></exception>
//        public static FlowRoot GetFlow(long FlowId)
//        {
//            if (FlowId <= 0)
//            {
//                throw new Exception("流程异常");
//            }
//            FlowBaseInfo BaseInfo = null;
//            FlowRoot Flow = null;
//            if (AppData.OpenFlows.ContainsKey(FlowId))
//            {
//                Flow = AppData.OpenFlows[FlowId];
//            }
//            else
//            {
//                BaseInfo = AppData.AllFlowBaseInfos[FlowId];
//                //foreach (FlowBaseInfo item in AppData.AllFlowBaseInfos)
//                //{
//                //    if (item.id == FlowId)
//                //    {
//                //        BaseInfo = item;
//                //        break;
//                //    }
//                //}
//                if (BaseInfo == null)
//                {
//                    LoggerService.Error("流程地址读取异常，空地址");
//                    return null;
//                }
//                Flow = FileHelper.ReadContent<FlowRoot>(BaseInfo.FilePath + "//" + BaseInfo.FileName);
//                if (Flow == null)
//                {
//                    LoggerService.Error("流程读取异常，空或未读取");
//                    return null;
//                }
//                Flow.name = BaseInfo.FileName;
//                Flow = DataPreprocessing(Flow);

//                AppData.AddOpenFlow(Flow);
//            }

//            if (Flow == null)
//            {
//                throw new Exception("找不到流程");
//            }

//            return Flow;
//        }

//        public static FlowRoot GetFlow2(string FolwPath)
//        {
//            FlowRoot Flow = FileHelper.ReadContent<FlowRoot>($"{FolwPath}");
//            if (Flow == null)
//            {
//                throw new Exception("");
//            }
//            return Flow;
//        }
//        /// <summary>
//        /// 更新流程
//        /// 
//        /// 同时通知UI更新
//        /// </summary>
//        /// <param name="Flow"></param>
//        /// <returns></returns>
//        public static void UpdateFlow(FlowRoot Flow, bool UpdateUI = true)
//        {
//            FlowBaseInfo flowInfo = AppData.GetFlowById(Flow.Id);
//            if (flowInfo == null)
//            {
//                throw new Exception("出错了，找不到流程");
//            }
//            string fj = Flow.ToJson(new[] { "Children", "Parents", "ParentKeyValue", "TotalSeconds", "Loggers", "Code", "nodeStatus", "NodeOutParam", "Logger", "backgroundColor", "NodeTotalSeconds" });

//            FileHelper.WriteContent($"{flowInfo.FilePath}//", flowInfo.FileName, fj);
//            // Flow = DataPreprocessing(Flow);
//            FlowRoot f = null;
//            AppData.OpenFlows.TryRemove(Flow.Id, out f);
//            if (UpdateUI)
//            {
//                JavaScriptEvent.Send(JavaScriptEventEnum.UPDATE_FLOW_DATA, fj);
//            }
//        }

//        private static object LockRunings = new object();

//        /// <summary>
//        /// 执行流程
//        /// </summary>
//        /// <param name="FolwId"></param>
//        internal static async void RunFlow(long FlowId)
//        {
//            if (!BaseService.AppConfig.field.EnableFlow)
//            {
//                LoggerService.Error($"流程执行被禁用");
//                return;
//            }
//            if (FlowId <= 0 || !AppData.AppRunSuccess || AppData.Runings.ContainsKey(FlowId))
//            {
//                LoggerService.Error($"流程未结束，无法执行下个流程，流程id={FlowId}，执行中的流程={AppData.Runings?.ToJson()}");
//                return;
//            }
//            Stopwatch SW = Stopwatch.StartNew();
//            FlowRoot Flow = GetFlow(FlowId);
//            if (Flow == null)
//            {
//                LoggerService.Error($"流程执行异常，请检查是否有对应的流程，流程id：{FlowId}");
//                return;
//            }
//            lock (LockRunings)
//            {
//                if (!AppData.Runings.ContainsKey(FlowId))
//                {
//                    try
//                    {
//                        AppData.Runings.TryAdd(FlowId, Flow);
//                    }
//                    catch (IndexOutOfRangeException ex)
//                    {
//                        LoggerService.Error("越界了：" + ex.Message, ex);
//                        LoggerService.Error($"Flow对象的相关属性值：[属性={Flow.ToJson()}, ");
//                        LoggerService.Error(ex.StackTrace);
//                        LoggerService.Error($"在添加FlowId为 {FlowId} 的元素时发生索引越界异常");
//                    }
//                }
//            }
//            AppData.RuningNodes[FlowId] = new ConcurrentBag<int>();

//            Init(Flow);
//            Flow.stopwatch = SW;
//            Flow.IsRuning = true;
//            Flow.TreeProcessors.ForEach(t =>
//            {
//                AppData.AddRuningNodeId(FlowId, t.id);
//                Task.Run(() =>
//                {
//                    try
//                    {
//                        Task FirstRun = t.ExecuteAsync(FlowId);
//                        if (FirstRun.Status == TaskStatus.Faulted)
//                        {
//                            t.NodeStatus = NodeStatusEnum.ERROR;
//                            Complete(t, NodeStatusEnum.ERROR);
//                        }
//                        LoggerService.Info($"记录节点状态：{t.NodeStatus}");
//                    }
//                    catch (Exception ex)
//                    {
//                        t.NodeStatus = NodeStatusEnum.ERROR;
//                        Complete(t, NodeStatusEnum.ERROR);
//                        LoggerService.Error($"节点执行异常，节点id：{t.id},原因：{ex.Message}", ex);
//                    }
//                });
//            });
//            OnRuning(Flow);
//        }

//        private static void Init(FlowRoot Flow)
//        {
//            Flow.processors.ForEach(f =>
//            {
//                f.ExecutionSource = new TaskCompletionSource<bool>();
//                f.NodeStatus = NodeStatusEnum.DEFAULT;
//                f.Logger = new NodeLogger();
//                f.stopwatch = new Stopwatch();
//                f.style.backgroundColor = "#fff";
//                foreach (NodeProcessor item in f.Children)
//                {
//                    item.ExecutionSource = new TaskCompletionSource<bool>();
//                    item.NodeStatus = NodeStatusEnum.DEFAULT;
//                    item.Logger = new NodeLogger();
//                    item.stopwatch = new Stopwatch();
//                    item.style.backgroundColor = "#fff";
//                }
//            });
//        }

//        /// <summary>
//        /// 监听运行中的流程
//        /// </summary>
//        public static void OnRuning(FlowRoot Flow)
//        {
//            long FlowId = Flow.Id;
//            _ = Task.Run(() =>
//            {
//                while ((bool)(AppData.Runings?.ContainsKey(FlowId)))
//                {
//                    bool ContainsKey = AppData.RuningNodes.ContainsKey(FlowId);
//                    ConcurrentBag<int> NodeIds = new ConcurrentBag<int>();
//                    if (AppData.RuningNodes.ContainsKey(FlowId))
//                    {
//                        NodeIds = AppData.RuningNodes[FlowId];
//                    }
//                    if (NodeIds?.Count > 0)
//                    {
//                        NodeIds = new ConcurrentBag<int>(NodeIds.Where(n => n != 0));
//                    }
//                    if (ContainsKey && NodeIds?.Count == 0)
//                    {
//                        try
//                        {
//                            StopFlow(FlowId);
//                        }
//                        catch (Exception ex)
//                        {
//                            LoggerService.Error($"监听流程结束时异常：{ex.Message}", ex);
//                        }
//                    }

//                    FlowOutTimeExit(Flow);
//                    Thread.Sleep(55);
//                }
//            });
//        }

//        /// <summary>
//        /// 流程超时退出
//        /// </summary>
//        /// <param name="Flow"></param>
//        private static void FlowOutTimeExit(FlowRoot Flow)
//        {
//            FlowBaseInfo item = AppData.AllFlowBaseInfos[Flow.Id];
//            if (Flow.stopwatch.Elapsed.TotalSeconds > item.OutTime)
//            {
//                StopFlow(item.id);
//                LoggerService.Warning($"流程超时自动停止,流程ID = {Flow.Id}");
//            }
//        }

//        /// <summary>
//        /// 终止流程
//        /// 
//        /// IsAuto = true 自动
//        /// IsAuto = false 手动
//        /// </summary>
//        /// <param name="FlowId"></param>
//        /// <param name="IsAuto"></param>
//        /// <returns></returns>
//        internal static bool StopFlow(long FlowId)
//        {
//            if (!AppData.Runings.ContainsKey(FlowId))
//            {
//                return true;
//            }
//            FlowRoot Flow = AppData.Runings[FlowId];
//            Flow.stopwatch.Stop();
//            TimeSpan elapsedTime = Flow.stopwatch.Elapsed;
//            Flow.FlowTotalSeconds = elapsedTime.TotalSeconds;

//            FlowRoot f = null;
//            AppData.Runings?.TryRemove(FlowId, out f);
//            if (AppData.RuningNodes.ContainsKey(FlowId))
//            {
//                int RemoveNode;
//                while (AppData.RuningNodes[FlowId].TryTake(out RemoveNode)) { }
//            }
//            //AppData.RuningNodes[FlowId].Clear();

//            ConcurrentBag<int> ids = new ConcurrentBag<int>();
//            AppData.RuningNodes.TryRemove(FlowId, out ids);
//            JavaScriptEvent.Send(JavaScriptEventEnum.FLOW_COMPLETE, Flow);
//            //JavaScriptEvent.Send(JavaScriptEventEnum.FLOW_COMPLETE, IsAuto? "流程终止" : "流程被手动终止");
//            return !AppData.Runings.ContainsKey(FlowId);
//        }

//        /// <summary>
//        /// 流程结束
//        /// </summary>
//        /// <param name="sW"></param>
//        /// <exception cref="NotImplementedException"></exception>
//        private static void FlowEnd(FlowRoot Flow, Stopwatch SW)
//        {
//            SW.Stop();
//            Flow.FlowTotalSeconds = SW.Elapsed.TotalSeconds;
//            JavaScriptEvent.Send(JavaScriptEventEnum.FLOW_COMPLETE, Flow);
//        }


//        /// <summary>
//        /// 转换数据结构
//        /// </summary>
//        /// <param name="Flow"></param>
//        /// <returns></returns>
//        private static FlowRoot DataPreprocessing(FlowRoot Flow)
//        {

//            //Flow.processors.Distinct().ToList().Sort((id1, id2) => id1.id.CompareTo(id2.id));
//            Dictionary<int, NodeProcessor> processors = Flow.processors.ToDictionary(p => p.id, p =>
//               {
//                   p.NodeStatus = NodeStatusEnum.DEFAULT;
//                   GetNodeDevice(p);
//                   p.SetNodeOutParamName();
//                   return p;
//               });

//            foreach (Connection connection in Flow.connections)
//            {
//                if (!processors.ContainsKey(connection.source) || !processors.ContainsKey(connection.target))
//                {
//                    continue;
//                }
//                NodeProcessor sourceProcessor = processors[connection.source];
//                NodeProcessor targetProcessor = processors[connection.target];

//                if (sourceProcessor.Children == null)
//                {
//                    sourceProcessor.Children = new List<NodeProcessor>();
//                }
//                sourceProcessor.Children.Add(targetProcessor);

//                if (targetProcessor.Parents == null)
//                {
//                    targetProcessor.Parents = new List<NodeProcessor>();
//                }
//                targetProcessor.Parents.Add(sourceProcessor);
//                //targetProcessor.ParentKeyValue.Add(sourceProcessor.id, sourceProcessor);
//                //SetParentKeyValue(targetProcessor, sourceProcessor);
//            }

//            List<NodeProcessor> tree = processors.Values.Where(p =>
//                !Flow.connections.Any(c => c.target == p.id)).ToList();

//            Flow.TreeProcessors = tree;

//            foreach (NodeProcessor item in Flow.processors)
//            {
//                SetParentKeyValue(item, item);
//            }
//            return Flow;
//        }

//        private static void SetParentKeyValue(NodeProcessor target, NodeProcessor source)
//        {
//            if (source.Parents != null)
//            {
//                foreach (NodeProcessor item in source.Parents)
//                {
//                    if (!target.ParentKeyValue.ContainsKey(item.id))
//                    {
//                        target.ParentKeyValue.Add(item.id, item);
//                    }
//                    SetParentKeyValue(target, item);
//                }
//            }
//        }

//        /// <summary>
//        /// 设置节点的设备
//        /// </summary>
//        /// <param name="p"></param>
//        private static void GetNodeDevice(NodeProcessor p)
//        {
//            int DataSourceId = p?.NodeInputParam?.NodePLC?.DataSourceId ?? -1;
//            if (p.PLCDevice != null || p.NodeInputParam == null || !AppData.IPLCHelpers.ContainsKey(DataSourceId))
//            {
//                return;
//            }

//            if (p.nodeType == NodeTypeEnum.PLC_WRITE)
//            {
//                p.PLCDevice = AppData.IPLCHelpers[DataSourceId];
//            }
//            if (p.nodeType == NodeTypeEnum.PLC_READ)
//            {
//                p.PLCDevice = AppData.IPLCHelpers[DataSourceId];
//            }
//            //if (p.NodeInputParam.DataSourceId > 0)
//            //{
//            //    p.PLCDevice = AppService.IPLCHelpers[p.NodeInputParam.DataSourceId];
//            //}

//        }
//    }
//}
